﻿using Core.Framework.Model.Common;
using Core.Framework.Redis;
using Core.Framework.Redis.Queue_Helper;
using Core.Framework.Util;
using Core.IBusiness.ILoggerModule;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.IO;
using System.Threading.Tasks;
using System.Web;

namespace Core.Middleware.ApiJson
{
    public class ApiJsonMidWare
    {
        private readonly RequestDelegate requestDelegate;

        /// <summary>
        /// 日志接口
        /// </summary>
        private ILog iLog = BuildServiceProvider.GetService<ILog>();

        public ApiJsonMidWare(RequestDelegate requestDelegate)
        {
            this.requestDelegate = requestDelegate;
        }

        public async Task Invoke(HttpContext context)
        {
            if (context.Request.Path == "/v1/.apiJson")
            {
                context.Response.ContentType = "application/json";

                // 用户身份验证
                if (context.Request.Method != "GET")
                {
                    var isHavClientInfo = context.Items.ContainsKey("ClientInfo");

                    if (!isHavClientInfo)
                    {
                        await context.Response.WriteAsync(new
                        {
                            code = 60003,
                            info = "接口禁止访问."
                        }.TryToJson());
                    }
                   
                }

                else {

                    context.Request.Headers["Itool-Data"]
                    = $"{context.Request.Headers["Itool-Data"]}_SqlServerConnection";


                    


                    string result = string.Empty;

                    var apiJsonDbContext = new ApiJsonDbContext(context);
                    var selectTable = new SelectTable(apiJsonDbContext, context);
                    var controller = new ApiJsonController(selectTable,apiJsonDbContext, context); 


                    switch (context.Request.Method)
                    {
                        // 查询
                        case "GET":
                            result = this.GETJSON(context, controller);
                            break;

                        // 添加
                        case "POST":
                            var readerPOST = new StreamReader(context.Request.Body);
                            var bodyPOST = readerPOST.ReadToEndAsync().Result;
                            result = controller.Add(bodyPOST).ToString();
                            break;

                        // 修改
                        case "PUT":
                            var readerPUT = new StreamReader(context.Request.Body);
                            var bodyPUT = readerPUT.ReadToEndAsync().Result;
                            result = controller.Edit(bodyPUT).ToString();
                            break;

                        // 删除
                        case "DELETE":
                            result = controller.Remove(context.Request.QueryString.ToString().TrimStart('?').Replace("=undefined", "")).ToString();
                            break;
                    }


                    await context.Response.WriteAsync(result);
                }


            }
            else {
                await requestDelegate(context);
            }
        }


        /// <summary>
        ///  获取数据
        /// </summary>
        /// <param name="context"></param>
        /// <param name="controller"></param>
        /// <returns></returns>
        private string GETJSON(HttpContext context, ApiJsonController controller) 
        {

            // 获取服务
            ApiProjectInfo iProjectInfo = (ApiProjectInfo)context.Items["ApiProjectInfo"];

            // 获取Redis服务
            var iRedis = BuildServiceProvider.GetService<IRedisHelper>();

            // 获取查询参数
            var query = context.Request.QueryString.ToString().TrimStart('?').Replace("=undefined", "");

            // 缓存KEY
            var cacheKey = $"{RedisQueueHelperParameter.APIJSON}{iProjectInfo.Token}_{Md5Helper.Hash(query.Trim())}";

            // 是否为 NoCache
            bool isNoCache = false;

            // 默认缓存时间
            int cacheSeconds = 60 * 60;

            // 检测是否保函缓存选择信息
            if (context.Request.Headers.ContainsKey("Itool-NoCache"))
            {
                // 是否为 NoCache
                isNoCache = context.Request.Headers["Itool-NoCache"].Equals("1");

                // NoCache 则缓存设置为 5S
                if (isNoCache)
                {
                    cacheSeconds = 6;
                    cacheKey = $"_MGT{cacheKey}";
                }
            }
            

            try
            {

                // 获取缓存
                var resultAsync = iRedis.GetAsync(cacheKey);

                // 拿到缓存数据
                var cache = resultAsync.Result;

                // 10S之内使用缓存
                if (!string.IsNullOrWhiteSpace(cache))
                {
                    return cache.ToString();
                }
                else
                {
                    throw new ArgumentNullException("查询数据库");
                }
            }
            catch
            {
                // 查询数据库
                string result = controller.Query(query).ToString();

                // 加入缓存
                iRedis.Set(cacheKey, result, TimeSpan.FromSeconds(cacheSeconds));

                // NoCache 则刷新缓存
                if (isNoCache)
                {
                    iRedis.Set(cacheKey.Replace("_MGT",""), result, TimeSpan.FromSeconds(cacheSeconds + 55));
                }

                // 返回结果
                return result;
            }


        }

    }
}
